package billrestauration.daos;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import org.hibernate.SessionFactory;
import org.springframework.orm.hibernate3.HibernateTemplate;
import org.springframework.stereotype.Repository;

import billrestauration.daos.interfaces.GestionRestaurantInterface;
import billrestauration.daos.interfaces.UtilisateurInterface;
import billrestauration.entities.Adresse;
import billrestauration.entities.GroupUtilisateur;
import billrestauration.entities.Groupe;
import billrestauration.entities.Menu;
import billrestauration.entities.Prix;
import billrestauration.entities.Reservation;
import billrestauration.entities.Role;
import billrestauration.entities.Utilisateur;

@Repository
public class MainDao implements GestionRestaurantInterface,UtilisateurInterface{
private HibernateTemplate template;
public void setSessionFactory(SessionFactory fact)
{
	this.template=new HibernateTemplate(fact,true);
}
public List  find(String HQL,Object ...param){return template.find(HQL,param);}
@Override
public Utilisateur loadUserByUsername(String username) {
	// TODO Auto-generated method stub
	List<Utilisateur> l = template.find("from  Utilisateur where username=?", username);
	if(null!=l&&l.size()>0){
		 
			return (Utilisateur) l.get(0);
		 
	}
	return null;
}
@Override
public List<Role> loadRoleByUsername(String username) {
	// TODO Auto-generated method stub
	 List<Role> l= template.find("from billrestauration.entities.Role where username=?", username);
	 String sql="select  new Role( g.id,ga.rolegroupe,g.nomgroupe ,gm.utilisateur)  "+
				" FROM Groupe g, GroupUtilisateur gm, GroupeRole ga  "+
				" WHERE gm.utilisateur.username = ? "+
				" AND g.nomgroupe = ga.groupe.nomgroupe  "+
				" AND g.nomgroupe = gm.groupe.nomgroupe ";
	List<Role>   ll =  (List<Role>) testJointure(sql, username);
	 
	 ll.addAll(l);
	 return ll;
	 
	 
}
@Override
public void update(Utilisateur u) {
	// TODO Auto-generated method stub
	Adresse adr=u.getAdresse();
	template.update(adr);
	u.setAdresse(adr);
	template.update(u);
}
@Override
public void addRole(Role role, Utilisateur u) {
	// TODO Auto-generated method stub
	 role.setUtilisateur(u);
	 if(null==loadUserByUsername(u.getUsername()))
		addUser(u);
	 template.save(role);
}
public void addRole(Role role ) {
	// TODO Auto-generated method stub
	addRole(role, role.getUtilisateur());
}
@Override
public void addRole(String role, Utilisateur u) {
	// TODO Auto-generated method stub
	addRole(new Role(0L, role, null, u), u);
}
public void addRole(String role, String u) {
	// TODO Auto-generated method stub
	Utilisateur uu=loadUserByUsername(u);
	if(null!=uu)
	addRole(new Role(0L, role, null, uu), uu);
}
@Override
public void addRole(String[] role, Utilisateur u) {
	// TODO Auto-generated method stub
	for (String string : role) {
		addRole(string,u);
	}
}
@Override
public void removeRole(String role, Utilisateur u) {
	// TODO Auto-generated method stub
	List<Role> l = loadRoleByUsername(u.getUsername());
	for (Role role2 : l) {
		if(role2.getRole().compareTo(role)==0)
			template.delete(role2);
			
	}
}
@Override
public void removeRole(String[] role, Utilisateur u) {
	// TODO Auto-generated method stub
	for (String string : role) {
		removeRole(string,u);
	}
}
@Override
public void addGroupe(Groupe g, Utilisateur u) {
	// TODO Auto-generated method stub
	
	if(null==loadGroupeByGroupeName(g.getNomgroupe()))
		template.save(g);
	if(null==loadRoleByUsername(u.getUsername()))
		template.save(u);
	GroupUtilisateur gu=new GroupUtilisateur(u,g);
	template.save(gu);
	 
}
@Override
public void addGroupe(String nomgroupe, Utilisateur u) {
	// TODO Auto-generated method stub
	addGroupe(new Groupe( nomgroupe), u);
}
@Override
public void removeGroupe(Groupe g, Utilisateur u) {
	// TODO Auto-generated method stub
	List l = template.find("from billrestauration.entities.GroupUtilisateur where refgroupe=? and username=?", g.getNomgroupe(),u.getUsername());
	if(null!=l&&l.size()>0){
		Object obj=l.get(0);
		if(obj instanceof GroupUtilisateur)
			template.delete(obj);
	}
}
@Override
public void removeGroupe(String nomgroupe, Utilisateur u) {
	// TODO Auto-generated method stub
	removeGroupe(new Groupe(nomgroupe), u);
}
@Override
public void addMenu(Menu m) {
	// TODO Auto-generated method stub
	Prix p=m.getPrix();
	template.saveOrUpdate(p);
	template.saveOrUpdate(m);
}
@Override
public void removeMenu(Menu m) {
	// TODO Auto-generated method stub
	// TODO Auto-generated method stub
		Prix p=m.getPrix();
		
		template.delete(m);
		template.delete(p);
}
@Override
public void addReservation(Reservation r) {
	// TODO Auto-generated method stub
	Menu m=r.getMenureserve();
	
	m.setQuantite(m.getQuantite()-r.getNombredepersonne());
	template.saveOrUpdate(m);
	Prix p=m.getPrix();
	 
	template.saveOrUpdate(p);
	m.setPrix(p);
	Utilisateur u=r.getClient();
	template.saveOrUpdate(u);
	template.saveOrUpdate(r);
}
@Override
public void removeReservation(Reservation r) {
	// TODO Auto-generated method stub
	r.setStatus(Reservation.ANNULEE);
	Menu m=r.getMenureserve();
	m.setQuantite(m.getQuantite()+1);
	template.update(m);
	template.update(r);
}
@Override
public int countReservation() {
	// TODO Auto-generated method stub
	 List<Reservation> l = listeReservation();
	 if(null==l)
	return 0;
	 return l.size();
}
@Override
public List<Reservation> listeReservation() {
	// TODO Auto-generated method stub
	return template.find("from billrestauration.entities.Reservation");
}
@Override
public boolean hasReservation(Reservation r, Utilisateur u) {
	// TODO Auto-generated method stub
	if(null==u)return false;
	//List<Reservation> l = template.find("from billrestauration.entities.Reservation where refutilisateur=?",u.getUsername());
	 return 0== r.getClient().getUsername().compareTo(u.getUsername());
	//return null!=l&&l.size()>0&&l.contains(r);
}
@Override
public boolean hasReservation(Reservation r, String u) {
	// TODO Auto-generated method stub
	return hasReservation(r,loadUserByUsername(u));
}
@Override
public List<Reservation> listeReservationByUser(Utilisateur u) {
	// TODO Auto-generated method stub
	List<Reservation> res=new ArrayList<Reservation>();
	List<Reservation> l = listeReservation();
	for (Reservation reservation : l) {
		if(reservation.getClient().getUsername().compareTo(u.getUsername())==0)
			res.add(reservation);
	}
	return res;
}
@Override
public List<Reservation> listeReservationByUser(String u) {
	// TODO Auto-generated method stub
	return listeReservationByUser(new Utilisateur(u));
}
@Override
public List<Reservation> listeReservationsEnCours() {
	// TODO Auto-generated method stub
	return  template.find("from billrestauration.entities.Reservation where status=?",new Integer(Reservation.EN_COURS));
	
}
@Override
public List<Reservation> listeReservationsTerminees() {
	// TODO Auto-generated method stub
	return  template.find("from billrestauration.entities.Reservation where status=?",new Integer(Reservation.TERMINEE));
	
}
@Override
public List<Reservation> listeReservationAnnulees() {
	// TODO Auto-generated method stub
	return  template.find("from billrestauration.entities.Reservation where status=?",new Integer(Reservation.ANNULEE));
	
}
@Override
public List<Reservation> listeReservationsEnCoursByUser(Utilisateur u) {
	// TODO Auto-generated method stub
	List<Reservation> l = listeReservationsEnCours();
	List<Reservation> res=new ArrayList<Reservation>();
	for (Reservation reservation : l) {
		if(reservation.getClient()==u)
			res.add(reservation);
	}
	return res;
}
public void save(Object obj){
	template.save(obj);
}
@Override
public List<Reservation> listeReservationsEnCoursByUser(String u) {
	// TODO Auto-generated method stub
	return listeReservationsEnCoursByUser(new Utilisateur(u));
}
@Override
public void addUser(Utilisateur u) {
	// TODO Auto-generated method stub
	System.out.println(u);
	Adresse ad=u.getAdresse();
	template.saveOrUpdate(ad);
	u.setAdresse(ad);
	template.save(u);
	
}
@Override
public Groupe loadGroupeByGroupeName(String groupename) {
	// TODO Auto-generated method stub
	List g = template.find("from billrestauration.entities.Groupe where nomgroupe=?",groupename );
	if(null!=g&&g.size()>0){
		return (Groupe) g.get(0);
	}
	return null;
}
@Override
public Menu findMenuByNom(String nom) {
	// TODO Auto-generated method stub
	List m= template.find("from billrestauration.entities.Menu where nom=?",nom );
	if(null!=m&&m.size()>0)
		return (Menu) m.get(0);
	return null;
}
public List<?> testJointure(String Sql,String ... param){
	return template.find(Sql,param);
}
@Override
public List<Menu> listeMenuDejeuner() {
	// TODO Auto-generated method stub
	return  template.find("from Menu where periode=?",Menu.DEJEUNER);
}
@Override
public List<Menu> listeMenuDiner() {
	// TODO Auto-generated method stub
	return  template.find("from Menu where periode=?",Menu.DINER);
}
@Override
public List<Menu> listeMenuPetitDejeuner() {
	// TODO Auto-generated method stub
	//System.out.println("from Menu where periode=? "+Menu.PETIT_DEJEUNER);
	return  template.find("from Menu where periode=?",Menu.PETIT_DEJEUNER);
}
@Override
public List<Menu> listeMenuDuJour() {
	// TODO Auto-generated method stub
	return  template.find("from Menu where estmenudujour=?",true);
}
@Override
public Menu findMenuById(Long id) {
	// TODO Auto-generated method stub
	List l = template.find("from Menu where id=?",id);
	if(null!=l&&l.size()>0)
		return (Menu)l.get(0);
	return null;
}
@Override
public Reservation findReservationById(Long id) {
	// TODO Auto-generated method stub
	List l = template.find("from Reservation where id=?",id);
	if(null!=l&&l.size()>0)
		return (Reservation)l.get(0);
	return null;
}
@Override
public List<Menu> listeMenu() {
	// TODO Auto-generated method stub
	return template.find("from Menu ");
}
@Override
public boolean supprimerMenu(Menu m) {
	// TODO Auto-generated method stub
	try{
		List<Reservation> lr=listeReservationByMenu(m);
		for (Reservation reservation : lr) {
			reservation.setMenureserve(null);
			template.update(reservation);
		}
		template.delete(m);
	}catch(Exception e){
		return false;
	}
	return true;
}
@Override
public boolean supprimerMenu(Long id) {
	// TODO Auto-generated method stub
	return supprimerMenu(findMenuById(id));
}
@Override
public List<Reservation> listeReservationByMenu(Menu m) {
	// TODO Auto-generated method stub
		return listeReservationByMenu(m.getId());
}
@Override
public List<Reservation> listeReservationByMenu(Long menuid) {
	// TODO Auto-generated method stub
	return template.find("from Reservation where refmenu=?",menuid);

}
@Override
public List<Utilisateur> findAllUsers() {
	// TODO Auto-generated method stub
	return template.find("from Utilisateur ");

}
}
